
package artistic;

/**
 *
 * @author Mikael Andersson
 * @author Rurik Högfeldt
 */
public class SimpleBrush extends Brush
{
    private ToolBox toolBox;
    public SimpleBrush(ToolBox toolBox)
    {
        this.toolBox = toolBox;
        buildCanvas();
    }

    private void buildCanvas()
    {
        brushCanvas = new TiledCanvas(width, height);
        for(int y=0; y<height; ++y)
        {
            for(int x=0; x<width; ++x)
            {
                double dx = x-(width/2);
                double dy = y-(height/2);

                //base alpha on distance from center
                double alpha = (int) (Math.sqrt((dx*dx)+(dy*dy))*255/width);
                int a  = 255-Math.min(255,(int) Math.min(alpha, 255)*2);
                
                brushCanvas.drawPixel(x, y, 0x00ffffff | (a<<24));
            }
        }
    }

    private TiledCanvas brushCanvas;

    private int width = 10, height = 10;
    public void setSize(int width, int height)
    {
        this.width = width;
        this.height = height;
        buildCanvas();
    }
    
    public void draw(TiledCanvas canvas, int x, int y)
    {
        int color = toolBox.getColorChooser().getFgColor() & 0x00ffffff;
        //canvas.drawPixel(x, y, 0x33000000 | color);

        int x1preClip=x-width/2;
        int x2preClip=x1preClip+width;
        int y1preClip=y-height/2;
        int y2preClip=y1preClip+height;

        int width = canvas.getWidth();
        int height = canvas.getHeight();

        if(x1preClip>=width)
            return;
        if(y1preClip>=height)
            return;
        if(x2preClip<0)
            return;
        if(y2preClip<0)
            return;

        int x1=Math.max(0, x1preClip);
        int y1=Math.max(0, y1preClip);
        int x2=Math.min(x2preClip, width-1);
        int y2=Math.min(y2preClip, height-1);

        int opacity = toolBox.getOpacity();

        CanvasTile[] tiles = canvas.getTiles();

        int tileIndex = canvas.getGridIndex(x1, y1);
        int gridWidth = canvas.getGridWidth();

        int startY = y1&63;
        int endX, endY;
        for(int gy=(y1>>6); gy<=(y2>>6); ++gy)
        {
            if((y2>>6)>gy)
                endY = 64;
            else
                endY = y2&63;

            int startX = x1&63;

            for(int gx=(x1>>6), i=0; gx<=(x2>>6); ++gx, ++i)
            {
                CanvasTile tile = tiles[tileIndex+i];
                
                if((x2>>6)>gx)
                    endX = 64;
                else
                    endX = x2&63;
                
                for(int yi=startY; yi<endY; ++yi)
                {
                    for(int xi=startX; xi<endX; ++xi)
                    {
                        int brushX = ((gx<<6)+xi)-x1preClip;
                        int brushY = ((gy<<6)+yi)-y1preClip;
                        int bColor = brushCanvas.getPixel(brushX, brushY);
                        int c = bColor & (color | 0xff000000);

                        tile.drawPixel(xi, yi, c, opacity);
                    }
                }
                
                startX = 0;
            }
            
            tileIndex+=gridWidth;
            startY = 0;
        }
    }
}
